/**
 * The Site Animation.
 * @returns {TrixterAnimation}
 */
function TrixterAnimation() {
      /**
       * Crate the stage for trixter. 
       * @type @exp;PIXI@call;Stage
       */
      var stage;

      /**
       * The canvas instace.
       * @type type
       */
      var view;
      /**
       * create a renderer instance
       * @type @exp;PIXI@call;autoDetectRenderer
       */
      var renderer;

      /**
       * create an empty container
       * @type @exp;PIXI@call;DisplayObjectContainer
       */
      var mainContainer;

      /**
       * create an empty container
       * @type @exp;PIXI@call;DisplayObjectContainer
       */
      var trixterContainer;

      /**
       * create an empty container
       * @type @exp;PIXI@call;DisplayObjectContainer
       */
      var middleContainer;

      /**
       * create an empty container
       * @type @exp;PIXI@call;DisplayObjectContainer
       */
      var staticPlataformesContainer;
      /**
       * The Bright Star TilingSprite.
       * @type @exp;PIXI@call;TilingSprite
       */
      var brightStar;

      /**
       * The cloud TilingSprite.
       * @type @exp;PIXI@call;TilingSprite
       */
      var clouds;

      /**
       * The space sprite.
       * @type @exp;PIXI@call;Sprite
       */
      var space;

      /*
       * The walker animation.
       * @type @exp;PIXI@call;MovieClip
       */
      var trixterWalker;

      /*
       * The elevator animation.
       * @type @exp;PIXI@call;MovieClip
       */
      var trixterElevator;
      
      /*
       * The elevator animation.
       * @type @exp;PIXI@call;Sprite
       */
      var trixterElevatorStatic;
     
      /*
       * The door tube.
       * @type @exp;PIXI@call;MovieClip
       */
      var trixterTube;
      
      /*
       * The door animation.
       * @type @exp;PIXI@call;MovieClip
       */
      var trixterDoor;

      /**
       * The jump sprite.
       * @type @exp;PIXI@call;Sprite
       */
      var trixterJump;

      /**
       * The idle sprite.
       * @type @exp;PIXI@call;Sprite
       */
      var trixterIdle;

      /**
       * Last position
       * @type object
       */
      var lastTrixterPosition;

      /**
       * Last position
       * @type object
       */
      var lastPagePosition;

      /**
       * 
       * @type boolean
       */
      var tl;

      var totalScrollSize;

      var timerID;
      /**
       * Start the Animation.
       * @returns {undefined}
       */
      this.init = function() {
            var assetsToLoader = ["img/sprite/atlas.json", "img/paralax/bright-star.png", "img/paralax/clouds.png"];

            var loader = new PIXI.AssetLoader(assetsToLoader);
            loader.onComplete = onAssetsLoaded;
            loader.load();

            stage = new PIXI.Stage(0x66FF99);

            view = $('#back-animation');

            totalScrollSize = $('html').height() - $(window).height();

            renderer = new PIXI.CanvasRenderer($(window).width(), $(window).height(), view[0], true);

            mainContainer = new PIXI.DisplayObjectContainer();
            mainContainer.position.x = 0;
            mainContainer.position.y = 0;
            stage.addChild(mainContainer);

            middleContainer = new PIXI.DisplayObjectContainer();
            middleContainer.position.x = view.width() / 2 - $('.default-width-and-center').width() / 2;
            middleContainer.position.y = 0;
            mainContainer.addChild(middleContainer);

            staticPlataformesContainer = new PIXI.DisplayObjectContainer();
            staticPlataformesContainer.position.x = 0;
            staticPlataformesContainer.position.y = 893;
            middleContainer.addChild(staticPlataformesContainer);

            trixterContainer = new PIXI.DisplayObjectContainer();
            trixterContainer.position.x = 0;
            trixterContainer.position.y = 135;
            middleContainer.addChild(trixterContainer);

            lastTrixterPosition = {
                  x: trixterContainer.position.x,
                  y: trixterContainer.position.y,
                  a: 1
            };

            lastPagePosition = {
                  x: window.pageXOffset,
                  y: window.pageXOffset
            };
      };

      /**
       * Listener to asstes load.
       * @returns {undefined}
       */
      var onAssetsLoaded = function() {
            
            loadTrixterAnimation();
            setStaticsPlataformes();
            
            brightStar = new PIXI.TilingSprite(
                    PIXI.Texture.fromImage("img/paralax/bright-star.png"),
                    801, 3478
                    );
            brightStar.position.x = middleContainer.position.x;
            brightStar.customAcelleration = 2;
            stage.addChild(brightStar);

            clouds = new PIXI.TilingSprite(
                    PIXI.Texture.fromImage("img/paralax/clouds.png"),
                    1024, $('body').height()
                    );
            stage.addChild(clouds);
            clouds.customAcelleration = 5;
            clouds.position.x = middleContainer.position.x;

            space = new PIXI.Sprite.fromImage("img/paralax/space.png");
            stage.addChild(space);
            space.position.x = middleContainer.position.x + (920 - 673) / 2;
            space.customAcelleration = 10;
            space.position.y = 654 - window.pageYOffset;

            window.onscroll = go;
            go();
            // start animating
            requestAnimFrame(animate);
      };

      /**
       * The cycle animation.
       * @returns {undefined}
       */
      var animate = function() {
            // render the stage;
            mainContainer.position.y = -window.pageYOffset;
            requestAnimFrame(animate);
            renderer.render(stage);
      };

      /**
       * Set the Trixter Animation;
       * @returns {undefined}
       */
      var loadTrixterAnimation = function() {
            var textures = [];
            for (var i = 1; i < 21; i++) {
                  textures.push(PIXI.Texture.fromFrame('walk-' + i));
            }
            trixterWalker = new PIXI.MovieClip(textures);
            trixterWalker.animationSpeed = (24 / 60);
            trixterContainer.addChild(trixterWalker);
            trixterWalker.play();
            trixterWalker.visible = false;
           
            var textures = [];
            for (var i = 1; i <= 20; i++) {
                  textures.push(PIXI.Texture.fromFrame('tube-' + i));
            }
            trixterTube = new PIXI.MovieClip(textures);
            trixterTube.animationSpeed = (24 / 60);
            trixterContainer.addChild(trixterTube);
            trixterTube.visible = false;
            trixterTube.loop = false;
            trixterTube.play();

            textures = [];
            for (i = 1; i <= 14; i++) {
                  textures.push(PIXI.Texture.fromFrame('elevator-' + i));
            }
            trixterElevator = new PIXI.MovieClip(textures);
            trixterElevator.animationSpeed = (24 / 60);
            trixterContainer.addChild(trixterElevator);
            trixterElevator.visible = false;
            trixterElevator.loop = false;
            trixterElevator.play();
            trixterElevatorStatic = createStaticPlataformes('elevator-1', 270 + trixterElevator.width, -trixterElevator.height, 1);
            
            textures = [];
            for (i = 1; i <= 12; i++) {
                  textures.push(PIXI.Texture.fromFrame('door-' + i));
            }
            trixterDoor = new PIXI.MovieClip(textures);
            trixterDoor.animationSpeed = (24 / 60);
            trixterContainer.addChild(trixterDoor);
            trixterDoor.visible = false;
            trixterDoor.loop = false;
            trixterDoor.play();

            trixterJump = PIXI.Sprite.fromFrame('jump');
            trixterContainer.addChild(trixterJump);

            trixterIdle = PIXI.Sprite.fromFrame('idle');
            trixterIdle.position.y = 17;
            trixterContainer.addChild(trixterIdle);
            trixterWalker.visible = trixterIdle;

            trixterContainer.position.x = 90;

            var plataformesPosition = staticPlataformesContainer.position.y - trixterWalker.height;

            tl = new TimelineMax();
            tl.to(trixterContainer.position, 400, {y: plataformesPosition}, 'jump-1')
                    .to(trixterContainer.position, 223, {x: 210 + trixterWalker.width / 2}, 'walker-1')
                    .to(trixterContainer.position, 194, {x: 210 + trixterWalker.width / 2}, 'idle-1')
                    .to(trixterContainer.position, 0,   {x: 302 + trixterWalker.width / 2})
                    .to(trixterContainer.position, 64,  {y: 291 + plataformesPosition, ease: Strong.easeOut, onComplete: openElevator}, 'elevator-1')
                    .to(trixterElevatorStatic.position, 64, {y: 292 + plataformesPosition - staticPlataformesContainer.position.y, ease: Strong.easeOut}, 'elevator-1')
                    .to(trixterContainer.position, 86,  {x: 176}, 'walker-3')
                    .to(trixterContainer.position, 36,  {x: 185, y:295 + plataformesPosition}, 'tube-1')
                    .to(trixterContainer.position, 200 ,{y: 983 + (plataformesPosition + trixterWalker.height) - trixterDoor.height, x:22 - trixterDoor.width/2.3}, 'door-1')
                    .to(trixterContainer.position, 100, {y: 983 + plataformesPosition, onComplete: openDoor}, 'door-2')
                    .to(trixterContainer.position, 0 ,  {y: 983 + plataformesPosition, x:80}, 'walker-5')
                    .to(trixterContainer.position, 28,  {x: 120}, 'walker-6')
                    .to(trixterContainer.position, totalScrollSize - (1393), {z: 0});
      };

      var openElevator = function() {
            trixterElevator.gotoAndPlay(0);
      };
      
      var openDoor = function() {
            trixterDoor.gotoAndPlay(0);
      };

      /**
       * Set statics plataformes;
       * @returns {undefined}
       */
      var setStaticsPlataformes = function() {
            createStaticPlataformes('plataformer', 84, 0, 3);

            createStaticPlataformes('plataformer', 1, 291, 2);
            createStaticPlataformes('plataformer-pipe', 176, 278, 1);
            createStaticPlataformes('plataformer', 261, 291, 1);

            createStaticPlataformes('plataformer', 99, 626, 6);

            createStaticPlataformes('plataformer-bottom', 342, 835, 1);

            createStaticPlataformes('door-1', 22 - trixterDoor.width/2.3, 983 - trixterDoor.height, 1);
            createStaticPlataformes('block', 22, 983, 4);

            createStaticPlataformes('plataformer', 15, 1332, 1);
            createStaticPlataformes('plataformer-bottom', 100, 1332, 1);
            createStaticPlataformes('plataformer', 186, 1332, 3);
            createStaticPlataformes('ladder', 104, 1366, 11, true);

            createStaticPlataformes('square', 100, 1715, 3);

            createStaticPlataformes('plataformer-bottom', 39, 1936, 1);

            createStaticPlataformes('square', 727, 1934, 2);

            createStaticPlataformes('plataformer-bottom', 60, 2226, 2);

            createStaticPlataformes('plataformer-bottom', 750, 2378, 1);

            createStaticPlataformes('bush', 298, 499, 1);
            createStaticPlataformes('bush', 286, 1232, 1);

            createStaticPlataformes('heart', 314, 1418, 4, false, 50);
            createStaticPlataformes('heart', 285, 1810, 3, false, 78);
            createStaticPlataformes('heart', 52, 1864, 1);
            createStaticPlataformes('heart', 115, 2146, 1);

            //After Cases.
            var marginTop = $('#contact').offset().top - staticPlataformesContainer.position.y;

            createStaticPlataformes('plataformer', 248, 13 + marginTop, 2);
            createStaticPlataformes('plataformer-pipe', 419, marginTop, 1);
            createStaticPlataformes('plataformer', 499, 13 + marginTop, 1);

            createStaticPlataformes('plataformer', 171, 814 + marginTop, 2);

            createStaticPlataformes('plataformer', 23, 1634 + marginTop, 1);
            createStaticPlataformes('plataformer-bottom', 109, 1634 + marginTop, 1);
            createStaticPlataformes('plataformer', 195, 1634 + marginTop, 1);
            createStaticPlataformes('plataformer-bottom', 281, 1634 + marginTop, 1);
            createStaticPlataformes('plataformer', 368, 1634 + marginTop, 6);
            createStaticPlataformes('ladder', 286, 1668 + marginTop, 4, true);
      };

      /**
       * Creat statics plataforms.
       * @param {string} plataformType - name of the frame;
       * @param {number} x - the x position;
       * @param {number} y - the y position;
       * @param {number} repeatNumber - Indicate repetition;
       * @param {boolean} repeatVertical - If repeat is if greater than 1, indicate the course.
       * @param {number} margin - If repeat is if greater than 1, indicate the margin between elements.
       * @returns { @type @exp;PIXI@call;Sprite}
       */
      var createStaticPlataformes = function(plataformType, x, y, repeatNumber, repeatVertical, margin) {
            margin = margin !== undefined ? margin : 0;

            var sprite;
            for (var i = 0; i < repeatNumber; i++) {
                  sprite = PIXI.Sprite.fromFrame(plataformType);

                  sprite.position.x = x;
                  sprite.position.y = y;

                  if (repeatVertical === true)
                        y += sprite.height + margin;
                  else
                        x += sprite.width + margin;

                  staticPlataformesContainer.addChild(sprite);
            };
            return sprite;
      };

      var go = function() {
            var between = window.pageYOffset;

            //Parallax
            brightStar.position.y = -between;
            if (between > lastPagePosition.y) {
                  brightStar.tilePosition.y -= brightStar.customAcelleration;
                  clouds.tilePosition.y -= clouds.customAcelleration;
                  space.position.y -= space.customAcelleration;
            }
            else if (between < lastPagePosition.y) {
                  brightStar.tilePosition.y += brightStar.customAcelleration;
                  clouds.tilePosition.y += clouds.customAcelleration;
                  space.position.y += space.customAcelleration;
            }

            tl.pause();
            tl.progress(Math.abs(between / totalScrollSize));

            setTrixterAnimation();

            lastTrixterPosition.x = trixterContainer.position.x;
            lastTrixterPosition.y = trixterContainer.position.y;
            lastTrixterPosition.a = trixterContainer.position.currentAnimation;

            lastPagePosition.y = between;
      };

      var setTrixterAnimation = function() {
            //Set trixter animation.
            trixterDoor.visible = false;
            trixterJump.visible = false;
            trixterIdle.visible = false;
            trixterTube.visible = false;
            trixterWalker.visible = false;
            trixterElevator.visible = false;
            
            var currentLabel = tl.currentLabel();
            console.log(currentLabel);
            
            if (currentLabel.indexOf('jump') >= 0) {
                  trixterJump.visible = true;
            }
            else if (currentLabel.indexOf('walker') >= 0) {
                  trixterWalker.visible = true;
                  if (lastTrixterPosition.x < trixterContainer.position.x) {
                        trixterWalker.position.x = 0;
                        trixterWalker.scale.x = 1;
                  }
                  else if (lastTrixterPosition.x > trixterContainer.position.x) {
                        trixterWalker.scale.x = -1;
                        trixterWalker.position.x = -trixterWalker.width;
                  } else {
                        trixterIdle.visible = true;
                        trixterWalker.visible = false;
                  }
            }
            else if (currentLabel.indexOf('elevator') >= 0) {
                  trixterElevator.visible = true;
            }
            else if (currentLabel.indexOf('door') >= 0) {
                  if(currentLabel !== 'door-1')
                        trixterDoor.visible = true;
            }
            else if (currentLabel.indexOf('tube') >= 0) {
                  trixterTube.visible = true;
                  if(!trixterTube.playing)
                        trixterTube.gotoAndPlay(0);
            }
            else if (currentLabel.indexOf('idle') >= 0) {
                 trixterIdle.visible = true;
            }

            if (timerID !== undefined)
                  clearTimeout(timerID);

            timerID = setTimeout(setTrixterAnimation, 200);
      };
}